function [TrueList] = Ddavid_recover_single_label_1(Data, TrueLabel, SampledTrueLabel, K, KNNList, R, T)

% [TrueList] = Ddavid_recover_single_label_1(Data, TrueLabel, SampledTrueLabel, K, KNNList, R, T)
%
% TightSVDD -> Loop(KNN -> SVDD)
%
% <Input>
% Data: [n*m], n is the number of instances, m is the number of features
% TrueLabel: [n*1], the value is {-1, 1}, the real answer of this label
% SampledTrueLabel: [n*1], the value is {-1, 1}, the sampled label
% K: The K value of KNN
% KNNList: The KNN List (for saving time)
% R: double, the relaxation parameter, R >= 0
% T: integer, the max relaxation times
%
% <Output>
% TrueList: [n*1], the value is {0, 1}

disp(['Ddavid_recover_single_label_1 R = ' num2str(R)]);

ArgMax = 0.5;
C = 1;
% K = 3;

[~, ArgCurrent, CurrentTrueList] = Ddavid_find_tightest_svdd(Data, SampledTrueLabel, R);

% Loop SVDD and KNN to add points
% KNNList = Ddavid_find_knn(K, Data');

CurrentT = 0;

while (ArgCurrent <= ArgMax)
    % Record the number of True points before KNN
    CurrentN = sum(CurrentTrueList == 1);

    % Add points to CurrentTrueList by KNN
    LastTrueList = CurrentTrueList;
    CurrentTrueList = Ddavid_add_points_by_knn(Data, TrueLabel, CurrentTrueList, K, KNNList);

    % Show the accuracy of added points
    AddedLabel = (LastTrueList == 0) & (CurrentTrueList == 1);
    if(sum(AddedLabel) > 0)
        CorrectAddedLabel = (AddedLabel == 1) & (TrueLabel == 1);
        disp(['  KNN Add ' num2str(sum(AddedLabel)) ' points, correct ' num2str(sum(CorrectAddedLabel)) ' points, ' num2str(sum(CorrectAddedLabel) / sum(AddedLabel) * 100) '%']);
    end
    
    % Record the number of True points after KNN
    NextN = sum(CurrentTrueList == 1);

    if(NextN == CurrentN)
        if(CurrentT < T)
            CurrentT = CurrentT + 1;
            disp(['ArgCurrent = ' num2str(ArgCurrent) ' -> ' num2str(ArgCurrent * 2)]);
            ArgCurrent = ArgCurrent * 2;
        else
            disp('  break by KNN');
            break;
        end
    end

    % Record the number of True points before SVDD
    CurrentN = sum(CurrentTrueList == 1);

    % Add points to CurrentTrueList by SVDD
    LastTrueList = CurrentTrueList;
    [~, CurrentTrueList] = Ddavid_add_points_by_svdd(Data, TrueLabel, CurrentTrueList, ArgCurrent);
    
    % Show the accuracy of added points
    AddedLabel = (LastTrueList == 0) & (CurrentTrueList == 1);
    if(sum(AddedLabel) > 0)
        CorrectAddedLabel = (AddedLabel == 1) & (TrueLabel == 1);
        disp(['  SVDD Add ' num2str(sum(AddedLabel)) ' points, correct ' num2str(sum(CorrectAddedLabel)) ' points, ' num2str(sum(CorrectAddedLabel) / sum(AddedLabel) * 100) '%']);
    end

    % Record the number of True points after SVDD
    NextN = sum(CurrentTrueList == 1);

    if(NextN == CurrentN)
        disp('  break by SVDD');
        break;
    end
end

TrueList = zeros(size(SampledTrueLabel, 1), 1);
TrueList(CurrentTrueList == 1) = 1;
TrueList(CurrentTrueList == 0) = -1;
